package com.vavr.checkincms.common.exception;

import java.util.Objects;

import com.vavr.checkincms.common.constant.CommonConstants;
import com.vavr.checkincms.common.domain.BaseResult;
import com.vavr.checkincms.common.domain.Result;
import com.vavr.checkincms.common.domain.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;

/**
 * ExceptionResolver
 *
 * @since 2.0.0
 */
@Slf4j
@Component
@RestControllerAdvice
public class ExceptionResolver {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public BaseResult<?> handleValidationExceptions(MethodArgumentNotValidException ex) {
        final FieldError fieldError = ex.getBindingResult().getFieldError();
        return BaseResult.of(new Result() {
            @Override
            public String getCode() {
                return String.valueOf(HttpStatus.BAD_REQUEST.value());
            }

            @Override
            public String getMsg() {
                return Objects.requireNonNull(fieldError).getDefaultMessage();
            }
        });
    }

    @ExceptionHandler(AsyncRequestTimeoutException.class)
    @ResponseBody
    public ResponseEntity<String> handleAsyncRequestTimeoutException(AsyncRequestTimeoutException ex) {
        log.error("连接超时！", ex);
        // 构造适合text/event-stream格式的异常消息
        String errorMessage = "event:" + CommonConstants.EventName.ON_STREAM_ERROR + '\n'
                + "data:{\"answer\":\"...连接超时！\"}" + '\n' + '\n' + " ";
        // 返回带有合适状态码的响应
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
    }

    @ExceptionHandler(BaseException.class)
    public BaseResult<?> handleBaseException(BaseException ex) {
        return BaseResult.of(ex.getResultEnum());
    }

    @ExceptionHandler(Exception.class)
    public BaseResult<?> handleException(Exception ex) {
        log.error("系统异常！", ex);
        return BaseResult.of(ResultEnum.ERROR);
    }
}
